"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 数据库系统
Case Name   : 一主两备，两个备节点同时重建
Create At   : 2020/07/25
@zou_jialiang0505328126
Description :
    1.备机1进行重建的同时备机2重建
    2.查询集群状态
    3.重复步骤1~2 5次
    4.执行TPCC
    5.验证主备数据是否一致
Expect      :
    1.备机1进行重建的同时备机2重建
    2.查询集群状态正常
    3.重复步骤1~2 5次
    4.执行TPCC成功
    5.验证主备数据一致
History     :
    2020/07/25  created by @wan005
    modified ：2020-12-4 by @peilinqian ；增加tpcc结果打印；
    modified ：2020-12-3 by @peilinqian ；删除与用例无关操作gs_dump；增加日志打印明细信息；
        优化整个用例风格
"""

import unittest

from testcase.utils.ComThread import *
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class DbsysCase138(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info('----this is setup----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.sta_1_sh = CommonSH('Standby1DbUser')
        self.sta_2_sh = CommonSH('Standby2DbUser')
        self.pri_dbuser = Node(node='PrimaryDbUser')
        self.pri_root = Node(node='PrimaryRoot')
        self.sta1_dbuser = Node(node='Standby1DbUser')
        self.sta1_root = Node(node='Standby1Root')
        self.sta2_dbuser = Node(node='Standby2DbUser')
        self.com = Common()
        self.constant = Constant()
        self.log.info('----Opengauss_Reliability_Dbsys_Case138 start----')

    def test_build_at_sametime(self):
        for i in range(1, 6):
            self.log.info("----循环第 " + str(i) + "次----")
            self.log.info("----循环第 " + str(i) + "次:备机1开始重建----")
            build_tread = ComThread(self.sta_1_sh.buildStandby, args=())
            build_tread.start()

            self.log.info("----循环第 " + str(i) + "次:备机2重建----")
            build_result = self.sta_2_sh.buildStandby()
            self.assertIn(self.constant.BUILD_SUCCESS_MSG, build_result)

            self.log.info("----循环第 " + str(i) + "次:备机1重建结果----")
            build_tread.join()
            build_result = build_tread.get_result()
            self.assertIn(self.constant.BUILD_SUCCESS_MSG, build_result)

            self.log.info('----同步是否正常----')
            self.pri_sh.check_location_consistency('primary', 3)
            self.log.info('----查询主备状态----')
            status = self.pri_sh.getDbClusterStatus('status')
            self.assertTrue(status)

        self.log.info('-----执行TPCC----')
        tpcc_result = self.com.startTPCC(self.pri_root, macro.TPCC_PATH)
        self.log.info(tpcc_result)
        self.assertIn(self.constant.TPCC_SUCCESS_MSG, tpcc_result)

        self.log.info('----同步是否正常----')
        self.pri_sh.check_location_consistency('primary', 3)
        self.log.info('----查询主备状态----')
        status = self.pri_sh.getDbClusterStatus('status')
        self.assertTrue(status)

        self.log.info('----查询主备数据是否一致----')
        nodes_tuple = (self.pri_dbuser,
                       self.sta1_dbuser,
                       self.sta2_dbuser)
        flag = self.com.check_data_sample_by_all(r'\d', *nodes_tuple)
        self.assertTrue(flag)

        table_dict = self.com.format_sql_result(
            self.pri_sh.executDbSql(r'\d'))
        table_name = table_dict.get('Name')
        for name in table_name:
            select_sql = f'select count(*) from {name};'
            flag = self.com.check_data_sample_by_all(select_sql,
                                                     *nodes_tuple)
            self.assertTrue(flag)

    def tearDown(self):
        self.log.info('----this is tearDown----')
        self.log.info('----Opengauss_Reliability_Dbsys_Case138 执行结束----')
